#    Copyright © 2019-2020 周曦 (zhou.xiii@qq.com)
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

module Zhouxi
  module Magiz_New
    def self.initial
      require "json"
      @cr = "Copyright © 2019-2020 Zhou Xi"
      @vr = "Version 0.4.2"
      @mdl = Sketchup.active_model
      @mts = @mdl.materials
      Dir.chdir(Sketchup.find_support_file("Patterns", "Plugins/Zhouxi_Magiz/"))
      c, p, @tp, @nm, @cb = "CLRS", "PTNS", ["Skyscraper", "TierBuilding", "Apartment", "Villa"], 0, [[0, 0, 0, 9, 9, 9, "NIL", 0, 0, 0, 0]]
      h = { c => {}, p => { @tp[0] => {}, @tp[1] => {}, @tp[2] => {}, @tp[3] => {} } }
      Dir["*.mgz"].each { |f|
        x = JSON.parse(File.read(f))
        h[c].merge! x[c] if x[c]
        @tp.each { |t| h[p][t].merge! x[p][t] if x[p][t] }
      }
      h[c].each { |k, v|
        @mts[k] ? m = @mts[k] : m = @mts.add(k)
        m.color = Sketchup::Color.new(v)
        m.alpha = 0.5 if k == "TSP"
      }
      @ptn = h[p]
    end

    initial

    def self.cube(e, p, w, d, h) #e为环境,p为原点,w为宽,d为长,h为高
      p1 = p + [w, 0, 0]
      p2 = p + [0, d, 0]
      p3 = p + [w, d, 0]
      c = e.add_group
      f = c.entities.add_face(p, p2, p3, p1)
      f.pushpull(-h, true)
      f.reverse!
      c
    end

    def self.dv1(g, f, n, s = 0) #参数：g为群组,f为面的位置(0-5)，n为分段数，s为两侧缩进，
      fs, ps = [], []
      g.entities.each { |e| fs << e if e.is_a? Sketchup::Face }
      vs = fs[f].vertices
      vs.each { |v| ps << v.position }
      eg = vs[0].edges - fs[f].edges
      vt = fs[f].normal.reverse
      vt.length = eg[0].length / n
      (1...n - s).each { |i|
        ps.map! { |p| p += vt }
        g.entities.add_edges(ps[0], ps[1], ps[2], ps[3], ps[0]) if i > s
      }
    end

    def self.dv2(g, f, n, s = 0) #g为群组,f为面的位置(0-5)，n为分段数，s为两侧缩进，
      fs, ps, li = [], [], []
      g.entities.each { |e| fs << e if e.is_a? Sketchup::Face }
      fs[f].edges.each { |e|
        p, vt = e.start.position, e.line[1]
        vt.length = e.length / n
        (1...n - s).each { |i| p += vt; ps << p if i > s }
      }
      vt = fs[f].normal.reverse
      vt.length = (fs[f].vertices[0].edges - fs[f].edges)[0].length
      ps.each { |p| li << [p, p + vt] }
      li.each { |l| g.entities.add_edges l }
    end

    def self.lv(t, m)
      s = (t.bounds.depth / m * 0.0254).round(0)
    end

    def self.create(t, a, d = 0) #t为目标组件，a为数组，d为细节
      case t
      when Sketchup::Group
        e = t.entities.add_group
      when Sketchup::ComponentInstance
        e = t.definition.entities.add_group
      end
      r1, r2, r3, r4, z = rand(2), rand(2), rand(2), rand(2), []
      a.each { |n| z << Array.new(n) }
      z.each { |n| (0..10).each { |i| n[i] = eval(n[i]) if n[i].is_a?(String) && i != 6 } }
      z.each { |n|
        if n[6] == "RND" && rand(2) == 1
        else
          c = cube(e.entities, Geom::Point3d.new(n[0], n[1], n[2]), n[3], n[4], n[5])
          n[6] == "NIL" ? c.material = nil : c.material = n[6]
          if d != 0 || n[7] == 0
            dv1(c, n[8], n[9], n[10]) if n[7] == 1
            dv2(c, n[8], n[9], n[10]) if n[7] == 2
          end
        end
      }
      e.transform! Geom::Transformation.rotation(e.bounds.center, Z_AXIS, 90.degrees * rand(4))
      e.transform! Geom::Transformation.new(e.bounds.min).inverse
      s = Geom::Transformation.scaling(
        t.definition.bounds.width / e.bounds.width,
        t.definition.bounds.height / e.bounds.height,
        t.definition.bounds.depth / e.bounds.depth,
      )
      e.transform! s
      t.definition.entities.each { |x| x.erase! if x != e }
      f = e.explode
      f[0].explode if a[0][7] == 0
    end

    def self.choose(t)
      if @nm == 0
        h = t.bounds.depth * 0.0254
        if h > 24
          x = @ptn[@tp[0]] if t.is_a? Sketchup::Group
          x = @ptn[@tp[2]] if t.is_a? Sketchup::ComponentInstance
        elsif h <= 24
          x = @ptn[@tp[1]] if t.is_a? Sketchup::Group
          x = @ptn[@tp[3]] if t.is_a? Sketchup::ComponentInstance
        end
        a = x.values[rand(x.values.size)]
      else
        a = @ptn[@nm[0]][@nm[1]]
      end
      a == nil ? a = @cb : a
    end

    def self.transform_all(d, c = 0) #c=1为重置体块
      @mdl.start_operation("transform", true)
      s, changed = @mdl.selection, []
      begin
        if s.size > 0
          s.each { |t|
            if t.is_a?(Sketchup::ComponentInstance) || t.is_a?(Sketchup::Group)
              c == 1 ? a = @cb : a = choose(t)
              create(t, a, d) if !changed.include?(t.definition)
              changed << t.definition if t.is_a?(Sketchup::ComponentInstance)
            end
          }
        end
      rescue
        initial
      end
      @mdl.commit_operation
    end

    @mgr = UI::HtmlDialog.new({ :dialog_title => "Pattern Manager", :scrollable => false, :resizable => false, :width => 300, :height => 300, :left => 75, :top => 90, :style => UI::HtmlDialog::STYLE_DIALOG })

    def self.show_mgr
      ui = "<!DOCTYPE html> <html lang='zh'> <head> <meta charset='UTF-8'> <style> html, body { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; font-family: Times; user-select: none; cursor: default; } div { height: 100%; } #trg { position: fixed; right: 6px; bottom: 6px; width: 27px; height: 27px; opacity: 0; cursor: pointer; z-index: 9; } #btn { transition: all 0.3s ease; position: fixed; right: 10px; bottom: 10px; width: 15px; height: 15px; padding: 5px; display: flex; justify-items: center; align-items: center; z-index: 8; background: #fff; } #btn div { transition: all 0.3s ease; position: relative; width: 100%; height: 2px; background: #000; } #btn div:before, #btn div:after { content: ''; width: 100%; height: 2px; background: #000; position: absolute; top: -5px; } #btn div:after { top: 5px; } #trg:hover+div div { transform: rotate(90deg); } #trg:hover+div div:before, #trg:hover+div div:after { top: 0; transform: rotate(90deg); } #trg:checked+div div { transform: rotate(45deg); } #trg:checked+div div:before, #trg:checked+div div:after { top: 0; transform: rotate(90deg); } #trg:checked:hover+div div { transform: rotate(225deg); } #trg:checked~#bar { top: 0; } #bar { transition: all 0.6s ease; position: fixed; top: -100%; left: 0; margin: 0; width: 100%; height: 100%; } #bar>div { position: relative; overflow: scroll; display: flex; flex-flow: row-reverse wrap-reverse; align-content: flex-start; background: #fff; height: 76%; padding: 9px; } #bar>div::-webkit-scrollbar { display: none; } #bar>div>div { position: relative; flex: auto; padding: 2px 2px; height: 25px; min-width:30px; 25px; line-height: 25px; text-align: center; font-family: Arial; color: #fff; } #bar>div>div>div:hover { color: #fff; background: #000; } .Skyscraper { background: #ffccbc; } .TierBuilding { background: #ffecb3; } .Apartment { background: #f0f4c3; } .Villa { background: #e8f5e9; } input { position: absolute; opacity: 0; } input:checked+div { color: #000; } #ttl { position: absolute; width: 100%; height: 100%; font-weight: bold; text-align: center; } p { position: absolute; top: 50%; width: 100%; font-size: 14px; } h1 { position: absolute; top: 15%; width: 100%; font-size: 60px; text-shadow: 5px 3px 3px #ddd; white-space:nowrap; } </style> <script type='text/javascript'> function set() { e = event.currentTarget; a = e.className; b = e.innerHTML; e.previousElementSibling.checked = true; c = document.getElementById('ttl').children; c[0].innerHTML = b; c[1].innerHTML = a; sketchup.getData(a + ',' + b) } </script> </head> <body> <div id='ttl'> <h1>MAGIZ</h1> <p>#{@cr}<br>#{@vr}</p> </div> <input type='checkbox' id='trg'> <div id='btn'> <div> </div> </div> <div id='bar'> <div>"
      @ptn.each_key { |t| @ptn[t].each_key { |k| ui += "<div><input type='radio' name='ptn'> <div class='#{t}' onclick='set()'>#{k}</div> </div>" } }
      ui += "</div></div></body></html>"
      @mgr.set_html(ui)
      @mgr.add_action_callback("getData") { |action_context, d| @nm = d.split(",") }
      @mgr.set_on_closed { @nm = 0 }
      @mgr.show
    end

    def self.toolbar
      d = "Resource/"
      i = [d + "icon1.svg", d + "icon2.svg", d + "icon3.svg", d + "icon4.svg"]
      tb = UI::Toolbar.new "Magiz"
      cm1 = UI::Command.new("Transform All") { transform_all(1) }
      cm1.small_icon = cm1.large_icon = i[0]
      cm1.status_bar_text = ("Transform all the groups and Components selected")
      cm1.tooltip = "Transform All"
      tb.add_item cm1
      cm2 = UI::Command.new("Simple Transformation") { transform_all(0) }
      cm2.small_icon = cm2.large_icon = i[1]
      cm2.status_bar_text = ("Transform all whithout details")
      cm2.tooltip = "Simple Transformation"
      tb.add_item cm2
      cm3 = UI::Command.new("Reset") { transform_all(0, 1) }
      cm3.small_icon = cm3.large_icon = i[2]
      cm3.status_bar_text = ("Transform to a cube")
      cm3.tooltip = "Reset"
      tb.add_item cm3
      cm4 = UI::Command.new("Reset") { @mgr.visible? ? @mgr.close : show_mgr }
      cm4.small_icon = cm4.large_icon = i[3]
      cm4.status_bar_text = ("Select a Pattern")
      cm4.tooltip = "Pattern Manager"
      tb.add_item cm4
      tb.show
    end

    toolbar
  end
end
